package com.hspedu.syn;

/**
 * @author DL5O
 * @version 1.0
 * 模拟线程死锁
 */

public class DeadLock {
    public static void main(String[] args) {
        DeadLockDemo A = new DeadLockDemo(true);
        A.setName("A线程");
        DeadLockDemo B = new DeadLockDemo(false);
        B.setName("B线程");
        A.start();
        B.start();
    }
}

//线程
class DeadLockDemo extends Thread{
    static Object o1 = new Object();
    static Object o2 = new Object();
    boolean flag;

    public DeadLockDemo(boolean flag){
        this.flag = flag;
    }

    @Override
    public void run() {
        //1.如果flag为T，线程就会先得到/持有 o1的对象锁，然后会尝试去得到o2的对先生
        //  当持有到 o2的对象锁时，才会继续往下执行
        //2.如果线程A 得不到o2的对象锁，就会Blocked
        //3.如果flag 为 false，线程会去得到o2的对象锁，
        //4.如果线程B 拿不到o1的对象锁，就会block
        if(flag){
            synchronized(o1){//对象互斥锁
                System.out.println(Thread.currentThread().getName()+"进入1");
                //拿到o1的锁之后会阻塞在这里，直到拿到o2的锁，
                // 此时第二个线程thread2进入，拿到o2的锁，进入堵塞状态，因为一直拿不到o1的锁，
                // o1又因为拿不到o2锁，释放不了，故成为了死锁
                synchronized (o2){
                    System.out.println(Thread.currentThread().getName()+"进行2");
                }
            }
        }else{
            synchronized (o2){

                //第二个线程 o1的锁已经被拿了，
                //这时，又想去拿o1的锁，但是o1在第36行阻塞到了，没有拿到o2的锁，没有释放，故这里也会被阻塞
                //那么这时就会产生一种死锁的情况，要避免
                System.out.println(Thread.currentThread().getName()+"进入3");
                synchronized (o1){
                    System.out.println(Thread.currentThread().getName()+"进行4");
                }
            }
        }
    }
}
